class XPromise {
  constructor(executor) {
    // 初始化状态
    this.state = 'pending'

    // 成功的值
    this.value = undefined
    // 失败的原因
    this.reason = undefined

    // 成功状态存放的数组
    this.onResolveCallbacks = []
    // 失败状态回调函数存放的数组
    this.onRejectCallbacks = []

    let resolve = value => {
      if (this.state === 'pending') {
        // 改变state状态
        this.state = 'fulfilled'
        // 存储成功的值
        this.value = value

        // 调用成功状态异步数组
        this.onRejectCallbacks.forEach(callback => {
          callback(this.value)
        })
      }
    }
    let reject = reason => {
      if (this.state === 'pending') {
        // 改变state状态
        this.state = 'rejected'
        // 存储错误原因
        this.reason = reason

        // 调用失败状态异步函数 数组
        this.onRejectCallbacks.forEach(callback => {
          callback(this.reason)
        })
      }
    }

    // 如果执行报错,直接执行reject

    try {
      executor(resolve, reject)
    } catch (err) {
      reject(err.message)
    }
  }

  // then方法,两个参数 onFulfilled 和 onRejected
  // then(onFulfilled, onRejected) {
  //   // 当状态为成功时, 传入成功的值
  //   if (this.state === 'fulfilled') {
  //     onFulfilled(this.value)
  //   }

  //   // 当状态失败时, 传入失败的原因
  //   if (this.state === 'rejected') {
  //     onRejected(this.reason)
  //   }

  //   // 当状态 未定时
  //   if (this.state === 'pending') {
  //     this.onResolveCallbacks.push(onFulfilled)
  //     this.onRejectCallbacks.push(onRejected)
  //   }
  // }

  // 不同的promise代码互相套用称为 resolvePromise 函数
  then(onFulfiled, onRejected) {
    // 声明返回promise2
    let promise2 = new XPromise((resolve, reject) => {
      if (this.state === 'fulfilled') {
        let x = onFulfiled(this.value)
        resolvePromise(promise2, x, resolve, reject)
      }
      if (this.state === 'rejected') {
        let x = onFulfiled(this.value)
        resolvePromise(promise2, x, resolve, reject)
      }
      if (this.state === 'pending') {
        this.onResolveCallbacks.push(() => {
          let x = onRejected(this.value)
          resolvePromise(promise2, x, resolve, reject)
        })
      }
    })
    return promise2
  }
}

function resolvePromise(promise2, x, resolve, reject) {
  // 循环引用报错
  if (x === promise2) {
    return reject(new TypeError('循环引用'))
  }
  // 防止多次调用
  let called
  // x不是null, 且x是对象或函数
  if (x != null && (typeof x === 'object' || typeof x === 'function')) {
    try {
      // 规定,声明then = x的then方法
      let then = x.then
      // 如果then是函数,就默认是promise了
      if (typeof then === 'function') {
        // 就让then执行第一个参数是this, 后面是成功的回调和失败的回调
        then.call(
          x,
          y => {
            // 成功和失败只能代用一个
            if (called) return
            called = true
            // resovle的结果已然是promise那就继续解析
            resolvePromise(promise2, y, resolve, reject)
          },
          err => {
            // 成功和失败只能调用一个
            if (called) return
            called = true
            reject(err)
          }
        )
      } else {
        resolve(x) //基本数据类型 直接成功
      }
    } catch (err) {
      // 也属于失败
      if (called) return
      called = true
      // 取消then出错了那就不要在执行了
      reject(err)
    }
  } else {
    resolve(x)
  }
}
